#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include "StdTcp.h"


extern char *key;

// 加密算法
void Encrypt(char *msg, char *key)
{
    for (int i = 0; i < strlen(msg); i++)
    {
        if (msg[i] <= 'z' && msg[i] >= 'a')
        {
            msg[i] = key[msg[i] - 'a'];
        }
    }
}

//解密函数
void Decrypt(char *msg, char *key)
{
    for (int i = 0; i < strlen(msg); i++)
    {
        if (msg[i] <= 'z' && msg[i] >= 'a')
        {
            for (int j = 0; j < 26; j++)
            {
                if (msg[i] == key[j])
                {
                    msg[i] = 'a' + j;
                    break;
                }
                
            }
            
        }
    }
}

struct StdTcpServer
{
    int sockfd;
};

/* 初始化服务器监听 */
TcpS *TcpServerInit(const char *ip, unsigned short port)
{
    TcpS *s = (TcpS *)malloc(sizeof(TcpS));
    if (s == NULL)
    {
        printf("Tcps malloc error\n");
        return NULL;
    }
    s->sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (s->sockfd < 0)
    {
        perror("sockfd");
        free(s);
        return NULL;
    }

    struct sockaddr_in localAddress;
    /* 清除脏数据 */
    memset(&localAddress, 0, sizeof(localAddress));
    localAddress.sin_family = AF_INET; // ipv4
    localAddress.sin_port = htons(port);
    localAddress.sin_addr.s_addr = inet_addr(ip);

    socklen_t localAddressLength = sizeof(localAddress);

    /* 绑定端口IP. */
    int ret = bind(s->sockfd, (const struct sockaddr *)&localAddress, localAddressLength);
    if (ret == -1)
    {
        perror("bind error");
        free(s);
        return NULL;
    }
    /* 设置端口复用 */
    int optVal = 1; // 是否启用 1就是启用，0不用
    ret = setsockopt(s->sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optVal, sizeof(optVal));
    if (ret == -1)
    {
        perror("setsockopt error");
        free(s);
        return NULL;
    }

    /* 监听套接字 */
    /* 10是最大的等待个数 */
    ret = listen(s->sockfd, 10);
    if (ret == -1)
    {
        perror("listen error");
        free(s);
        return NULL;
    }

    return s;
}

int TcpServerAccept(TcpS *s)
{
    struct sockaddr_in clientAddr;
    socklen_t len = sizeof(clientAddr);
    int clientSock = accept(s->sockfd, (struct sockaddr *)&clientAddr, &len);
    if (clientSock < 0)
    {
        perror("accept");
        return -1;
    }
    return clientSock;
}

/* 服务器发送数据 */
bool TcpServerSend(int ClientSock, void *p, size_t size)
{
    //Encrypt(p, key);
    if ((send(ClientSock, p, size, 0)) < 0)
    {
        perror("send");
        return false;
    }
    return true;
}

bool TcpServerRecv(int ClientSock, void *p, size_t size)
{
    //Decrypt(p, key);
    if ((recv(ClientSock, p, size, 0)) <= 0)
    {
        perror("recv");
        return false;
    }
    return true;
}

void ClearTcpServer(TcpS *s)
{
    close(s->sockfd);
    free(s);
}

struct StdTcpClient
{
    int sockfd;
};

TcpC *TcpClientInit(const char *Serverip, unsigned short Serverport)
{
    TcpC *c = (TcpC *)malloc(sizeof(TcpC));
    if (c == NULL)
    {
        perror("TcpC malloc error");
        return NULL;
    }

    c->sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (c->sockfd == -1)
    {
        perror("socket error");
        free(c);
        return NULL;
    }

    struct sockaddr_in localAddress;
    /* 清除脏数据 */
    memset(&localAddress, 0, sizeof(localAddress));
    localAddress.sin_family = AF_INET; // ipv4
    localAddress.sin_port = htons(Serverport);
    localAddress.sin_addr.s_addr = inet_addr(Serverip);
    socklen_t localAddressLength = sizeof(localAddress);

    int ret = connect(c->sockfd, (const struct sockaddr *)&localAddress, localAddressLength);
    if (ret == -1)
    {
        perror("connect error");
        free(c);
        return NULL;
    }

    return c;
}

bool TcpClientSend(TcpC *c, void *p, size_t size)
{
    //Encrypt(p, key);
    if ((send(c->sockfd, p, size, 0)) < 0)
    {
        perror("send");
        return false;
    }
    return true;
}

bool TcpClientRecv(TcpC *c, void *p, size_t size)
{
    //Decrypt(p, key);
    
    if ((recv(c->sockfd, p, size, 0)) <= 0)
    {
        perror("recv");
        return false;
    }

    return true;
}

void ClearTcpClient(TcpC *c)
{
    close(c->sockfd);
    free(c);
}
